//  Copyright  2006, Peter Kellner, 73rd Street Associates
//  All rights reserved.
//  http://PeterKellner.net
//
//
//  - Neither Peter Kellner, nor the names of its
//  contributors may be used to endorse or promote products
//  derived from this software without specific prior written
//  permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES INCLUDING,
//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//  POSSIBILITY OF SUCH DAMAGE.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Web.Profile;

namespace MembershipUtilities
{

    [DataObject(true)]
    public class MembershipUserAndProfileODS
    {

        [DataObjectMethod(DataObjectMethodType.Insert, true)]
        public void Insert(string userName, bool isApproved,
            string comment, DateTime lastLockoutDate, DateTime creationDate,
            string email, DateTime lastActivityDate, string providerName, bool isLockedOut,
            DateTime lastLoginDate, bool isOnline, string passwordQuestion,
            DateTime lastPasswordChangedDate, string password, string passwordAnswer
                 , string firstname, string surname, int customerID, int websiteID
            )
        {

            MembershipCreateStatus status;
            Membership.CreateUser(userName, password, email, passwordQuestion, passwordAnswer, isApproved, out status);

            if (status != MembershipCreateStatus.Success)
            {
                throw new ApplicationException(status.ToString());
            }

            MembershipUser mu = Membership.GetUser(userName);
            mu.Comment = comment;
            Membership.UpdateUser(mu);
            ProfileBase profile = ProfileBase.Create(mu.UserName, true);
            profile.SetPropertyValue("Firstname", firstname);
            profile.SetPropertyValue("Surname", surname);
            profile.SetPropertyValue("CustomerID", customerID);
            profile.SetPropertyValue("WebsiteID", websiteID);
            profile.Save();
        }

        [DataObjectMethod(DataObjectMethodType.Delete, true)]
        static public void Delete(string UserName)
        {
            Membership.DeleteUser(UserName, true);
        }

        [DataObjectMethod(DataObjectMethodType.Delete, false)]
        static public void Delete(string UserName, string original_UserName)
        {
            string userNameForDelete = String.IsNullOrEmpty(UserName) ? original_UserName : UserName;
            Membership.DeleteUser(userNameForDelete, true);
        }

        [DataObjectMethod(DataObjectMethodType.Update, false)]
        public void Update(string UserName, string original_UserName, string email, bool isLockedOut,
             bool isApproved, string comment, DateTime lastActivityDate, DateTime lastLoginDate
             , string firstname, string surname, int customerID, int websiteID
        )
        {
            string userNameForUpdate = String.IsNullOrEmpty(UserName) ? original_UserName : UserName;
            this.Update(userNameForUpdate, email, isLockedOut, isApproved, comment, lastActivityDate, lastLoginDate
                 , firstname, surname, customerID, websiteID
            );
        }



        [DataObjectMethod(DataObjectMethodType.Update, true)]
        public void Update(string userName, string email, bool isLockedOut,
             bool isApproved, string comment, DateTime lastActivityDate, DateTime lastLoginDate
                  , string firstname, string surname, int customerID, int websiteID
        )
        {
            bool dirtyFlagMu = false;

            MembershipUser mu = Membership.GetUser(userName);

            ProfileBase profile = ProfileBase.Create(mu.UserName, true);
            profile.SetPropertyValue("Firstname", firstname);
            profile.SetPropertyValue("Surname", surname);
            profile.SetPropertyValue("CustomerID", customerID);
            profile.SetPropertyValue("WebsiteID", websiteID);
            profile.Save();

            if (mu.IsLockedOut && !isLockedOut)
            {
                mu.UnlockUser();
            }

            if (string.IsNullOrEmpty(mu.Comment) || mu.Comment.CompareTo(comment) != 0)
            {
                dirtyFlagMu = true;
                mu.Comment = comment;
            }

            if (string.IsNullOrEmpty(mu.Email) || mu.Email.CompareTo(email) != 0)
            {
                dirtyFlagMu = true;
                mu.Email = email;
            }

            if (mu.IsApproved != isApproved)
            {
                dirtyFlagMu = true;
                mu.IsApproved = isApproved;
            }

            if (dirtyFlagMu == true)
            {
                Membership.UpdateUser(mu);
            }
        }


        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<MembershipUserWrapperForMP> GetMembers()
        {
            return GetMembers(true, true, null, null);
        }

        [DataObjectMethod(DataObjectMethodType.Select, true)]
        public List<MembershipUserWrapperForMP> GetMembers(string sortData)
        {
            return GetMembers(true, true, null, sortData);
        }

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<MembershipUserWrapperForMP> GetMembers(int WebsiteID, string rolesToInclude, string SortData)
        {
            List<MembershipUserWrapperForMP> users = GetMembers(SortData);
            List<MembershipUserWrapperForMP> returnList = new List<MembershipUserWrapperForMP>();
            string[] roles = rolesToInclude.Split(',');
            foreach (MembershipUserWrapperForMP user in users)
            {
                if (user.WebsiteID == WebsiteID)
                {
                    if (rolesToInclude == "*")
                        returnList.Add(user);
                    else
                    {
                        foreach (string role in roles)
                        {
                            if (Roles.IsUserInRole(user.UserName, role))
                            {
                                returnList.Add(user);
                                break;
                            }
                        }
                    }
                }
            }

            return returnList;
        }

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<MembershipUserWrapperForMP> GetMembers(bool approvalStatus, string sortData)
        {
            if (approvalStatus == true)
            {
                return GetMembers(true, false, null, sortData);
            }
            else
            {
                return GetMembers(false, true, null, sortData);
            }
        }

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<MembershipUserWrapperForMP> GetMembers(bool returnAllApprovedUsers, bool returnAllNotApprovedUsers,
            string usernameToFind, string sortData)
        {

            List<MembershipUserWrapperForMP> memberList = new List<MembershipUserWrapperForMP>();

            if (usernameToFind != null)
            {
                MembershipUser mu = Membership.GetUser(usernameToFind);
                if (mu != null)
                {
                    MembershipUserWrapperForMP md = new MembershipUserWrapperForMP(mu);
					ProfileBase profile = ProfileBase.Create(mu.UserName, true);
		            md.Firstname = (string)profile.GetPropertyValue("Firstname");
		            md.Surname = (string)profile.GetPropertyValue("Surname");
		            md.CustomerID = (int)profile.GetPropertyValue("CustomerID");
		            md.WebsiteID = (int)profile.GetPropertyValue("WebsiteID");
                    memberList.Add(md);
                }
            }
            else
            {
                MembershipUserCollection muc = Membership.GetAllUsers();
                foreach (MembershipUser mu in muc)
                {
                    if ((returnAllApprovedUsers == true && mu.IsApproved == true) ||
                         (returnAllNotApprovedUsers == true && mu.IsApproved == false))
                    {
                        MembershipUserWrapperForMP md = new MembershipUserWrapperForMP(mu);
                        ProfileBase profile = ProfileBase.Create(mu.UserName, true);
			            md.Firstname = (string)profile.GetPropertyValue("Firstname");
			            md.Surname = (string)profile.GetPropertyValue("Surname");
			            md.CustomerID = (int)profile.GetPropertyValue("CustomerID");
			            md.WebsiteID = (int)profile.GetPropertyValue("WebsiteID");
	                    memberList.Add(md);
                    }
                }

                if (sortData == null)
                {
                    sortData = "UserName";
                }
                if (sortData.Length == 0)
                {
                    sortData = "UserName";
                }

                string sortDataBase = sortData; // init and assume there is not DESC appended to sortData
                string descString = " DESC";
                if (sortData.EndsWith(descString))
                {
                    sortDataBase = sortData.Substring(0, sortData.Length - descString.Length);
                }

                Comparison<MembershipUserWrapperForMP> comparison = null;

                switch (sortDataBase)
                {

                    case "Firstname":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                           delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                           {
                               if (lhs.Firstname == null || rhs.Firstname == null)
                               {
                                   return 1;
                               }
                               else
                               {
                                   return lhs.Firstname.CompareTo(rhs.Firstname);
                               }
                           }
                         );
                        break;
                    case "Surname":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                           delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                           {
                               if (lhs.Surname == null || rhs.Surname == null)
                               {
                                   return 1;
                               }
                               else
                               {
                                   return lhs.Surname.CompareTo(rhs.Surname);
                               }
                           }
                         );
                        break;
                    case "CustomerID":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                           delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                           {
                               if (lhs.CustomerID == null || rhs.CustomerID == null)
                               {
                                   return 1;
                               }
                               else
                               {
                                   return lhs.CustomerID.CompareTo(rhs.CustomerID);
                               }
                           }
                         );
                        break;
                    case "WebsiteID":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                           delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                           {
                               if (lhs.WebsiteID == null || rhs.WebsiteID == null)
                               {
                                   return 1;
                               }
                               else
                               {
                                   return lhs.WebsiteID.CompareTo(rhs.WebsiteID);
                               }
                           }
                         );
                        break;
                    case "UserName":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                            delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                            {
                                return lhs.UserName.CompareTo(rhs.UserName);
                            }
                            );
                        break;
                    case "Email":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                             delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                             {
                                 if (lhs.Email == null || rhs.Email == null)
                                 {
                                     return 0;
                                 }
                                 else
                                 {
                                     return lhs.Email.CompareTo(rhs.Email);
                                 }
                             }
                             );
                        break;
                    case "CreationDate":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                             delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                             {
                                 return lhs.CreationDate.CompareTo(rhs.CreationDate);
                             }
                             );
                        break;
                    case "IsApproved":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                             delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                             {
                                 return lhs.IsApproved.CompareTo(rhs.IsApproved);
                             }
                             );
                        break;
                    case "IsOnline":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                             delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                             {
                                 return lhs.IsOnline.CompareTo(rhs.IsOnline);
                             }
                             );
                        break;
                    case "LastLoginDate":
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                             delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                             {
                                 return lhs.LastLoginDate.CompareTo(rhs.LastLoginDate);
                             }
                             );
                        break;
                    default:
                        comparison = new Comparison<MembershipUserWrapperForMP>(
                             delegate(MembershipUserWrapperForMP lhs, MembershipUserWrapperForMP rhs)
                             {
                                 return lhs.UserName.CompareTo(rhs.UserName);
                             }
                             );
                        break;
                }

                if (sortData.EndsWith("DESC"))
                {
                    memberList.Sort(comparison);
                    memberList.Reverse();
                }
                else
                {
                    memberList.Sort(comparison);
                }

            }

            return memberList;

        }


    }

    public class MembershipUserWrapperForMP : MembershipUser
    {

        public MembershipUserWrapperForMP(MembershipUser mu)
            : base(mu.ProviderName, mu.UserName, mu.ProviderUserKey, mu.Email, mu.PasswordQuestion,
            mu.Comment, mu.IsApproved, mu.IsLockedOut, mu.CreationDate, mu.LastLoginDate, mu.LastActivityDate,
            mu.LastPasswordChangedDate, mu.LastLockoutDate)
        {
        }

        [DataObjectField(true)]
        public override string UserName
        {
            get { return base.UserName; }
        }

        public MembershipUserWrapperForMP() { }
        public MembershipUserWrapperForMP(string firstname, string surname, int customerID, int websiteID)
        {
            this.firstname = firstname;
            this.surname = surname;
            this.customerID = customerID;
            this.websiteID = websiteID;
        }

        private string firstname;
        [DataObjectField(false, false, false)]
        public string Firstname
        {
            get { return firstname; }
            set { firstname = value; }
        }

        private string surname;
        [DataObjectField(false, false, false)]
        public string Surname
        {
            get { return surname; }
            set { surname = value; }
        }

        private int customerID;
        [DataObjectField(false, false, false)]
        public int CustomerID
        {
            get { return customerID; }
            set { customerID = value; }
        }

        private int websiteID;
        [DataObjectField(false, false, false)]
        public int WebsiteID
        {
            get { return websiteID; }
            set { websiteID = value; }
        }






    }


    [DataObject(true)]  // This attribute allows the
    public class RoleDataObjectForMP
    {

        [DataObjectMethod(DataObjectMethodType.Select, true)]
        static public List<RoleDataForMP> GetRoles()
        {
            return GetRoles(null, false);
        }

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        static public List<RoleDataForMP> GetRoles(string userName, bool showOnlyAssignedRolls)
        {
            List<RoleDataForMP> roleList = new List<RoleDataForMP>();

            string[] roleListStr = Roles.GetAllRoles();
            foreach (string roleName in roleListStr)
            {
                bool userInRole = false;
                if (userName != null)
                {
                    userInRole = Roles.IsUserInRole(userName, roleName);
                }

                if (showOnlyAssignedRolls == false || userInRole == true)
                {
                    string[] usersInRole = Roles.GetUsersInRole(roleName);
                    RoleDataForMP rd = new RoleDataForMP();
                    rd.RoleName = roleName;
                    rd.UserName = userName;
                    rd.UserInRole = userInRole;
                    rd.NumberOfUsersInRole = usersInRole.Length;
                    roleList.Add(rd);
                }
            }

            return roleList;
        }

        [DataObjectMethod(DataObjectMethodType.Insert, true)]
        static public void Insert(string roleName)
        {
            if (Roles.RoleExists(roleName) == false)
            {
                Roles.CreateRole(roleName);
            }
        }

        [DataObjectMethod(DataObjectMethodType.Delete, true)]
        static public void Delete(string roleName)
        {
            MembershipUserCollection muc = Membership.GetAllUsers();
            string[] allUserNames = new string[1];

            foreach (MembershipUser mu in muc)
            {
                if (Roles.IsUserInRole(mu.UserName, roleName) == true)
                {
                    allUserNames[0] = mu.UserName;
                    Roles.RemoveUsersFromRole(allUserNames, roleName);
                }
            }
            Roles.DeleteRole(roleName);
        }
    }

    public class RoleDataForMP
    {

        private int numberOfUsersInRole;
        public int NumberOfUsersInRole
        {
            get { return numberOfUsersInRole; }
            set { numberOfUsersInRole = value; }
        }

        private string roleName;
        [DataObjectField(true)]
        public string RoleName
        {
            get { return roleName; }
            set { roleName = value; }
        }

        private string userName;
        public string UserName
        {
            get { return userName; }
            set { userName = value; }
        }

        private bool userInRole;
        public bool UserInRole
        {
            get { return userInRole; }
            set { userInRole = value; }
        }

    }
}



